﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;

namespace Microsoft.WowAddonStudio.FrameXml.Serialization
{
	[Serializable]
    public abstract class SerializationObject
    {
        /// <summary>
        /// Get or sets the unknown <see cref="XmlElement"/>s.
        /// </summary>
        /// <remarks>
        /// All unknown <see cref="XmlElement"/>s found during deserialization are collected here and are correctly serialized back.
        /// </remarks>
        [XmlAnyElement]
        [Browsable(false)]
        public XmlElement[] UnknownElements { get; set; }

        /// <summary>
        /// Get or sets the unknown <see cref="XmlAttribute"/>s.
        /// </summary>
        /// <remarks>
        /// All unknown <see cref="XmlAttribute"/>s found during deserialization are collected here and are correctly serialized back.
        /// </remarks>
        [XmlAnyAttribute]
        [Browsable(false)]
        public XmlAttribute[] UnknownAttributes { get; set; }

        /// <summary>
        /// Gets a value indicating whether a serialization object is complete and can be rendered.
        /// </summary>
        [XmlIgnore]
        [Browsable(false)]
        public virtual bool IsComplete
        {
            get { return false; }
        }

        /// <summary>
        /// Initializes the default values for the properties.
        /// </summary>
        protected void InitializeDefaults()
        {
            foreach (var propertyInfo in this.GetType().GetProperties())
            {
                var defaultValueAttribute = propertyInfo.GetCustomAttributes(typeof(DefaultValueAttribute), true).OfType<DefaultValueAttribute>()
                                                                                                                 .SingleOrDefault();

                if (defaultValueAttribute != null)
                    propertyInfo.SetValue(this, defaultValueAttribute.Value, null);
            }
        }

        /// <summary>
        /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </returns>
        public override string ToString()
        {
			return String.Format(CultureInfo.InvariantCulture, "{{{0}}}", this.GetType().Name);
        }
    }
}
